{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[this doc on github](https://github.com/dotnet/interactive/tree/main/samples/notebooks/powershell)\n",
    "\n",
    "# Charts with XPlot using constructors <img src=\"https://raw.githubusercontent.com/PowerShell/PowerShell/master/assets/Powershell_black_64.png\" align=\"right\"/>\n",
    "Charts can be rendered using [Xplot.Plotly](https://fslab.org/XPlot/). \n",
    "We will cover some example on how to use XPlot in a notebook with .NET Interactive.\n",
    "\n",
    "> NOTE: This and \"Plotting with Xplot using type accelerators\" produce the same output. They're just using different scripting mechanisms."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "csharp"
    }
   },
   "outputs": [],
   "source": [
    "#!csharp\r\n",
    "#r \"nuget: XPlot.Plotly.Interactive, 4.0.6\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Rendering Scatter plots\n",
    "One of the most commonly used type of chart to explore data set. Use the type `Graph.Scatter`."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$openSeries = [Graph.Scatter]::new()\n",
    "$openSeries.name = \"Open\"\n",
    "$openSeries.x = @(1, 2, 3, 4)\n",
    "$openSeries.y = @(10, 15, 13, 17)\n",
    "\n",
    "$closeSeries = [Graph.Scatter]::new()\n",
    "$closeSeries.name = \"Close\"\n",
    "$closeSeries.x = @(2, 3, 4, 5)\n",
    "$closeSeries.y = @(16, 5, 11, 9)\n",
    "\n",
    "$chart = @($openSeries, $closeSeries) | New-PlotlyChart -Title \"Open vs Close\"\n",
    "Out-Display $chart"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's change it to be markers style, so more like a scatter plot."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$openSeries.mode = \"markers\";\n",
    "$closeSeries.mode = \"markers\";\n",
    "\n",
    "$chart = @($openSeries, $closeSeries) | New-PlotlyChart -Title \"Open vs Close\"\n",
    "Out-Display $chart"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`Scatter` can also produce polar charts by setting the radial property `r` and angular proeprty `t`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$openSeries = [Graph.Scatter]::new()\n",
    "$openSeries.name = \"Open\"\n",
    "$openSeries.r = @(1, 2, 3, 4)\n",
    "$openSeries.t = @(45, 100, 150, 290)\n",
    "\n",
    "$closeSeries = [Graph.Scatter]::new()\n",
    "$closeSeries.name = \"Close\"\n",
    "$closeSeries.r = @(2, 3, 4, 5)\n",
    "$closeSeries.t = @(16, 45, 118, 90)\n",
    "\n",
    "$layout = [Layout]::new()\n",
    "$layout.title = \"Open vs Close\"\n",
    "$layout.orientation = -90\n",
    "\n",
    "$chart = @($openSeries, $closeSeries) | New-PlotlyChart -Layout $layout\n",
    "$chart | Out-Display"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Large scatter plots and performance\n",
    "It is not uncommon to have scatter plots with a large dataset, it is a common scenario at the beginning of a data exploration process. Using the default `svg` based rendering will create performace issues as the dom will become very large.\n",
    "We can then use `web-gl` support to address the problem."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "#!time\n",
    "$series = 1..10 | ForEach-Object {\n",
    "    $trace = [Graph.Scattergl]::new()\n",
    "    $trace.name = \"Series $_\"\n",
    "    $trace.mode = \"markers\"\n",
    "    $trace.x = [double[]](Get-Random -Count 100000 -Minimum -100000 -Maximum 100000)\n",
    "    $trace.y = [double[]](Get-Random -Count 100000 -Minimum -100000 -Maximum 100000)\n",
    "\n",
    "    $trace\n",
    "}\n",
    "\n",
    "New-PlotlyChart -Title \"Large Dataset\" -Trace $series | Out-Display"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Can provide custom marker `colour`, `size` and `colorscale` to display even more information to the user."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$series | ForEach-Object {\n",
    "    [int[]] $sizes = Get-Random -Count 100 -Minimum 0.0 -Maximum 1.0 |\n",
    "        ForEach-Object { $_ -lt 0.75 ? (Get-Random -Minimum 1 -Maximum 5) : (Get-Random -Minimum 10 -Maximum 15) }\n",
    "    $temperatures = $sizes | ForEach-Object { ($_ * 10) - 100 }\n",
    "\n",
    "    $_.x = [double[]](Get-Random -Count 100000 -Minimum -100000 -Maximum 100000)\n",
    "    $_.y = [double[]](Get-Random -Count 100000 -Minimum -100000 -Maximum 100000)\n",
    "    $_.marker = [XPlot.Plotly.Marker]::new()\n",
    "    $_.marker.size = $sizes\n",
    "    $_.marker.color = $temperatures\n",
    "    $_.marker.colorscale = \"hot\"\n",
    "}\n",
    "\n",
    "New-PlotlyChart -Title \"Large Dataset\" -Trace $series | Out-Display"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plotly pvoides some additional `color scales` to use."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "foreach ($trace in $series) {\n",
    "    $trace.marker.colorscale = \"Viridis\"\n",
    "}\n",
    "\n",
    "New-PlotlyChart -Title \"Viridis scale\" -Trace $series | Out-Display\n",
    "\n",
    "foreach ($trace in $series) {\n",
    "    $trace.marker.colorscale = \"Hot\"\n",
    "}\n",
    "\n",
    "New-PlotlyChart -Title \"Hot scale\" -Trace $series | Out-Display\n",
    "\n",
    "foreach ($trace in $series) {\n",
    "    $trace.marker.colorscale = \"Jet\"\n",
    "}\n",
    "\n",
    "New-PlotlyChart -Title \"Jet scale\" -Trace $series | Out-Display"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Rendering Histograms\n",
    "Let's have a look at using histograms, the next cell sets up some generators."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$count = 20\n",
    "[datetime[]] $dates = 1..$count | ForEach-Object { (Get-Date).AddMinutes((Get-Random -Minimum $_ -Maximum ($_+30))) }"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now let's define histogram traces:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$openByTime = [Graph.Histogram]::new()\n",
    "$openByTime.name = \"Open\"\n",
    "$openByTime.x = $dates\n",
    "$openByTime.y = [double[]](Get-Random -Count $count -Minimum 0 -Maximum 200)\n",
    "\n",
    "$closeByTime = [Graph.Histogram]::new()\n",
    "$closeByTime.name = \"Close\"\n",
    "$closeByTime.x = $dates\n",
    "$closeByTime.y = [double[]](Get-Random -Count $count -Minimum 0 -Maximum 200)\n",
    "\n",
    "New-PlotlyChart -Trace @($openByTime, $closeByTime) | Out-Display"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Histogram generator will automatically count the number of items per bin. \n",
    "\n",
    "Setting `histfunc` to `\"sum\"` we can now add up all the values contained in each bin.\n",
    "Note that we are creatng bin using the `x` data point and we are using bydefault autobinx"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$openByTime.histfunc = 'sum'\n",
    "$closeByTime.histfunc = 'sum'\n",
    "\n",
    "(New-PlotlyChart -Trace @($openByTime, $closeByTime)) | Out-Display"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Area chart and Polar Area chart"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By populating hte property `fill` of a `Scatter` trace the chart will render as area chart.\n",
    "\n",
    "Here is set to `\"tozeroy\"` which will create a fill zone underneath the line reachin to the 0 of the y axis."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$openSeries = [Graph.Scatter]::new()\n",
    "$openSeries.name = \"Open\"\n",
    "$openSeries.x = @(1, 2, 3, 4)\n",
    "$openSeries.y = @(10, 15, 13, 17)\n",
    "$openSeries.fill = \"tozeroy\"\n",
    "$openSeries.mode = \"lines\"\n",
    "\n",
    "$closeSeries = [Graph.Scatter]::new()\n",
    "$closeSeries.name = \"Close\"\n",
    "$closeSeries.x = @(1, 2, 3, 4)\n",
    "$closeSeries.y = @(3, 5, 11, 9)\n",
    "$closeSeries.fill = \"tozeroy\"\n",
    "$closeSeries.mode = \"lines\"\n",
    "\n",
    "$chart = @($openSeries, $closeSeries) | New-PlotlyChart -Title \"Open vs Close\"\n",
    "Out-Display $chart"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With one `fill` set to `\"tonexty\"` the cahrt will fill the aread between traces."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$openSeries.fill = $null;\n",
    "$closeSeries.fill = \"tonexty\";\n",
    "\n",
    "$chart = @($openSeries, $closeSeries) | New-PlotlyChart -Title \"Open vs Close\"\n",
    "Out-Display $chart"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using `Area` traces we can generate radial area chart. In this example we are using cardinal points to xpress angular values.\n",
    "The array `{\"North\", \"N-E\", \"East\", \"S-E\", \"South\", \"S-W\", \"West\", \"N-W\"}` will be autoimatically translated to angular values."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "dotnet_interactive": {
     "language": "pwsh"
    }
   },
   "outputs": [],
   "source": [
    "$areaTrace1 = [Graph.Area]::new()\n",
    "$areaTrace1.r = @(77.5, 72.5, 70.0, 45.0, 22.5, 42.5, 40.0, 62.5)\n",
    "$areaTrace1.t = @(\"North\", \"N-E\", \"East\", \"S-E\", \"South\", \"S-W\", \"West\", \"N-W\")\n",
    "$areaTrace1.name = \"11-14 m/s\"\n",
    "$areaTrace1.marker = [XPlot.Plotly.Marker]::new()\n",
    "$areaTrace1.marker.color = \"rgb(106,81,163)\"\n",
    "\n",
    "$areaTrace2 = [Graph.Area]::new()\n",
    "$areaTrace2.r = @(57.49999999999999, 50.0, 45.0, 35.0, 20.0, 22.5, 37.5, 55.00000000000001)\n",
    "$areaTrace2.t = @(\"North\", \"N-E\", \"East\", \"S-E\", \"South\", \"S-W\", \"West\", \"N-W\")\n",
    "$areaTrace2.name = \"8-11 m/s\"\n",
    "$areaTrace2.marker = [XPlot.Plotly.Marker]::new()\n",
    "$areaTrace2.marker.color = \"rgb(158,154,200)\"\n",
    "\n",
    "$areaTrace3 = [Graph.Area]::new()\n",
    "$areaTrace3.r = @(40.0, 30.0, 30.0, 35.0, 7.5, 7.5, 32.5, 40.0)\n",
    "$areaTrace3.t = @(\"North\", \"N-E\", \"East\", \"S-E\", \"South\", \"S-W\", \"West\", \"N-W\")\n",
    "$areaTrace3.name = \"5-8 m/s\"\n",
    "$areaTrace3.marker = [XPlot.Plotly.Marker]::new()\n",
    "$areaTrace3.marker.color = \"rgb(203,201,226)\"\n",
    "\n",
    "$areaTrace4 = [Graph.Area]::new()\n",
    "$areaTrace4.r = @(20.0, 7.5, 15.0, 22.5, 2.5, 2.5, 12.5, 22.5)\n",
    "$areaTrace4.t = @(\"North\", \"N-E\", \"East\", \"S-E\", \"South\", \"S-W\", \"West\", \"N-W\")\n",
    "$areaTrace4.name = \"< 5 m/s\"\n",
    "$areaTrace4.marker = [XPlot.Plotly.Marker]::new()\n",
    "$areaTrace4.marker.color = \"rgb(242,240,247)\"\n",
    "\n",
    "$areaLayout = [Layout]::new()\n",
    "$areaLayout.title = \"Wind Speed Distribution in Laurel, NE\"\n",
    "$areaLayout.font = [XPlot.Plotly.Font]::new()\n",
    "$areaLayout.font.size = 16\n",
    "$areaLayout.legend = [XPlot.Plotly.Legend]::new()\n",
    "$areaLayout.legend.font = [XPlot.Plotly.Font]::new()\n",
    "$areaLayout.legend.font.size = 16\n",
    "$areaLayout.radialaxis = [XPlot.Plotly.Radialaxis]::new()\n",
    "$areaLayout.radialaxis.ticksuffix = \"%\"\n",
    "$areaLayout.orientation = 270\n",
    "\n",
    "New-PlotlyChart -Layout $areaLayout -Trace @($areaTrace1, $areaTrace2, $areaTrace3, $areaTrace4) | Out-Display"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": ".NET (PowerShell)",
   "language": "PowerShell",
   "name": ".net-powershell"
  },
  "language_info": {
   "file_extension": ".ps1",
   "mimetype": "text/x-powershell",
   "name": "PowerShell",
   "pygments_lexer": "powershell",
   "version": "7.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}